package com.cw.iwc;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.BoundCamera;
import org.anddev.andengine.engine.handler.IUpdateHandler;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLayer;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXProperties;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTile;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTileProperty;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTiledMap;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader.ITMXTilePropertiesListener;
import org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXLoadException;
import org.anddev.andengine.entity.primitive.Rectangle;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.shape.IShape;
import org.anddev.andengine.entity.shape.modifier.LoopShapeModifier;
import org.anddev.andengine.entity.shape.modifier.PathModifier;
import org.anddev.andengine.entity.shape.modifier.PathModifier.IPathModifierListener;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import org.anddev.andengine.util.Debug;
import org.anddev.andengine.util.Path;
import org.anddev.andengine.util.constants.Constants;

import com.cw.iwc.cooldown.BaseCDTimer;
import com.cw.iwc.cooldown.ICDUpdateListener;

import android.util.Log;
import android.widget.Toast;

public class InterstellarWarChessActivity extends BaseGameActivity {

    // ===========================================================
    // Constants
    // ===========================================================
    private static final String TAG = "Test";
    
    private static final int CAMERA_WIDTH = 480;

    private static final int CAMERA_HEIGHT = 320;

    // ===========================================================
    // Fields
    // ===========================================================

    private BoundCamera mBoundChaseCamera;

    private Texture mTexture;

    private TiledTextureRegion mPlayerTextureRegion;

    private TMXTiledMap mTMXTiledMap;

    protected int mCactusCount;

    // ===========================================================
    // Constructors
    // ===========================================================

    // ===========================================================
    // Getter & Setter
    // ===========================================================

    // ===========================================================
    // Methods for/from SuperClass/Interfaces
    // ===========================================================

    public Engine onLoadEngine() {
        // Unit test
        class TestListener implements ICDUpdateListener {

            public void onCDStart() {
                Log.d(TAG, "OnStart");
            }

            public void onCDReset() {
                Log.d(TAG, "onCDReset");
            }

            public void onCDUpdate(long millisecondElapsed) {
                Log.d(TAG, "onCDUpdate:" + millisecondElapsed);
            }

            public void onCDFinished() {
                // TODO Auto-generated method stub
                Log.d(TAG, "onCDFinished");
            }
            
        }
        
        BaseCDTimer timer = new BaseCDTimer(new TestListener(), 770);
        timer.initTimer(0, 12000);
        timer.setTimer(5000);
        timer.startTimer();
        
        
        this.mBoundChaseCamera = new BoundCamera(0, 0, CAMERA_WIDTH,
                CAMERA_HEIGHT);
        return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE,
                new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),
                this.mBoundChaseCamera));
    }

    public void onLoadResources() {
        this.mTexture = new Texture(128, 128, TextureOptions.DEFAULT);
        this.mPlayerTextureRegion = TextureRegionFactory.createTiledFromAsset(
                this.mTexture, this, "gfx/player.png", 0, 0, 3, 4); // 72x128

        this.mEngine.getTextureManager().loadTexture(this.mTexture);
    }

    public Scene onLoadScene() {
        this.mEngine.registerUpdateHandler(new FPSLogger());

        final Scene scene = new Scene(2);

        try {
            final TMXLoader tmxLoader = new TMXLoader(this,
                    this.mEngine.getTextureManager(),
                    TextureOptions.BILINEAR_PREMULTIPLYALPHA,
                    new ITMXTilePropertiesListener() {

                        public void onTMXTileWithPropertiesCreated(
                                final TMXTiledMap pTMXTiledMap,
                                final TMXLayer pTMXLayer,
                                final TMXTile pTMXTile,
                                final TMXProperties<TMXTileProperty> pTMXTileProperties) {
                            /*
                             * We are going to count the tiles that have the
                             * property "cactus=true" set.
                             */
                            if (pTMXTileProperties.containsTMXProperty(
                                    "stone", "true")) {
                                InterstellarWarChessActivity.this.mCactusCount++;
                            }
                        }
                    });
            this.mTMXTiledMap = tmxLoader.loadFromAsset(this, "tmx/test1.tmx");
//            this.mTMXTiledMap = tmxLoader.loadFromAsset(this, "tmx/desert.tmx");

            Toast.makeText(this,
                    "Cactus count in this TMXTiledMap: " + this.mCactusCount,
                    Toast.LENGTH_LONG).show();
        } catch (final TMXLoadException tmxle) {
            Debug.e(tmxle);
        }

        final TMXLayer tmxLayer = this.mTMXTiledMap.getTMXLayers().get(0);
        scene.getBottomLayer().addEntity(tmxLayer);

        /* Make the camera not exceed the bounds of the TMXLayer. */
        this.mBoundChaseCamera.setBounds(0, tmxLayer.getWidth(), 0,
                tmxLayer.getHeight());
        this.mBoundChaseCamera.setBoundsEnabled(true);

        /*
         * Calculate the coordinates for the face, so its centered on the
         * camera.
         */
        final int centerX = (CAMERA_WIDTH - this.mPlayerTextureRegion
                .getTileWidth()) / 2;
        final int centerY = (CAMERA_HEIGHT - this.mPlayerTextureRegion
                .getTileHeight()) / 2;

        /* Create the sprite and add it to the scene. */
        final AnimatedSprite player = new AnimatedSprite(centerX, centerY,
                this.mPlayerTextureRegion);
        this.mBoundChaseCamera.setChaseShape(player);

        final Path path = new Path(5).to(0, 0).to(0, 300).to(300, 300)
                .to(300, 0).to(0, 0);

        player.addShapeModifier(new LoopShapeModifier(new PathModifier(30,
                path, null, new IPathModifierListener() {

                    public void onWaypointPassed(
                            final PathModifier pPathModifier,
                            final IShape pShape, final int pWaypointIndex) {
                        switch (pWaypointIndex) {
                        case 0:
                            player.animate(new long[] { 200, 200, 200 }, 6, 8,
                                    true);
                            break;
                        case 1:
                            player.animate(new long[] { 200, 200, 200 }, 3, 5,
                                    true);
                            break;
                        case 2:
                            player.animate(new long[] { 200, 200, 200 }, 0, 2,
                                    true);
                            break;
                        case 3:
                            player.animate(new long[] { 200, 200, 200 }, 9, 11,
                                    true);
                            break;
                        }
                    }
                })));

        /*
         * Now we are going to create a rectangle that will always highlight the
         * tile below the feet of the player.
         */
        final Rectangle currentTileRectangle = new Rectangle(0, 0,
                this.mTMXTiledMap.getTileWidth(),
                this.mTMXTiledMap.getTileHeight());
        currentTileRectangle.setColor(1, 0, 0, 0.25f);
        scene.getTopLayer().addEntity(currentTileRectangle);

        scene.registerUpdateHandler(new IUpdateHandler() {

            public void reset() {
            }

            public void onUpdate(final float pSecondsElapsed) {
                /* Get the scene-coordinates of the players feet. */
                final float[] playerFootCordinates = player
                        .convertLocalToSceneCoordinates(12, 31);
                /* Get the tile the feet of the player are currently waking on. */
                final TMXTile tmxTile = tmxLayer.getTMXTileAt(
                        playerFootCordinates[Constants.VERTEX_INDEX_X],
                        playerFootCordinates[Constants.VERTEX_INDEX_Y]);
                if (tmxTile != null) {
                    // tmxTile.setTextureRegion(null); <-- Rubber-style removing
                    // of tiles =D
                    currentTileRectangle.setPosition(tmxTile.getTileX(),
                            tmxTile.getTileY());
                }
            }
        });
        scene.getTopLayer().addEntity(player);

        return scene;
    }

    public void onLoadComplete() {

    }

    // ===========================================================
    // Methods
    // ===========================================================

    // ===========================================================
    // Inner and Anonymous Classes
    // ===========================================================

}